package com.hsteach.service.activity;

import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.hsteach.common.core.domain.model.AuthInfo;
import com.hsteach.common.core.page.TableDataInfo;
import com.hsteach.common.exception.ServiceException;
import com.hsteach.common.utils.DateUtils;
import com.hsteach.common.utils.PageUtils;
import com.hsteach.common.utils.SecurityUtils;
import com.hsteach.common.utils.StringUtils;
import com.hsteach.dao.domain.activity.*;
import com.hsteach.dao.mapper.activity.ActivityFilesMapper;
import com.hsteach.dao.mapper.activity.ActivitiesMapper;
import com.hsteach.dao.mapper.activity.ActivityClassMapper;
import com.hsteach.dao.mapper.activity.ActivityEnrollMapper;
import com.hsteach.enums.BooleanEnum;
import com.hsteach.enums.ActivityFileTypeEnum;
import com.hsteach.enums.DeleteStatusEnum;
import com.hsteach.framework.feign.IdentityEnum;
import com.hsteach.framework.feign.client.xgk.dto.ret.GetClassListByIdsRet;
import com.hsteach.framework.feign.client.xgk.dto.ret.GetSchoolPartTreeRet;
import com.hsteach.framework.web.service.AuthService;
import com.hsteach.service.third.XgkService;
import com.hsteach.web.controller.activity.dto.ActivityFileDto;
import com.hsteach.web.controller.activity.dto.AddActivityDto;
import com.hsteach.web.controller.activity.dto.UpdateActivityDto;
import com.hsteach.web.controller.activity.sdk.dto.ListActivitiesSdkDto;
import com.hsteach.web.controller.activity.sdk.vo.ListActivitiesSdkVo;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 活动列表Service业务层处理
 *
 * @author ruoyi
 * @date 2023-07-07
 */
@Service
public class ActivitiesService {
    @Autowired
    private ActivitiesMapper activitiesMapper;

    @Autowired
    private ActivityClassMapper activityClassMapper;

    @Autowired
    private ActivityEnrollMapper activityEnrollMapper;

    @Autowired
    private ActivityFilesMapper activityFilesMapper;

    @Autowired
    private XgkService xgkService;

    @Autowired
    private AuthService authService;

    /**
     * 查询活动列表
     *
     * @param id 活动列表主键
     * @return 活动列表
     */
    public Activities selectTbActivitiesById(Long id) {
        Activities activities = activitiesMapper.selectTbActivitiesById(id);
        if (activities.getStatus().equals(0)){
            throw new ServiceException("活动已删除");
        }
        ActivityFiles activityFiles = new ActivityFiles();
        activityFiles.setActivityId(id);
        List<ActivityFiles> allFiles = activityFilesMapper.selectActivityFilesList(activityFiles);
        List<String> imgs = Lists.newArrayList();
        List<ActivityFileDto> files = Lists.newArrayList();
        allFiles.stream().forEach(e -> {
            if (ActivityFileTypeEnum.IMG.getCode().equals(e.getFileType())) {
                imgs.add(e.getUrl());
            } else {
                ActivityFileDto dto = new ActivityFileDto();
                dto.setUrl(e.getUrl());
                dto.setFileName(e.getFileName());
                dto.setFileExt(e.getFileExt());
                files.add(dto);
            }
        });
        activities.setImgs(imgs);
        activities.setFiles(files);
        ActivityClass activityClass = new ActivityClass();
        activityClass.setActivityId(id);
        List<ActivityClass> activityClasses = activityClassMapper.selectTbActivityClassList(activityClass);
        activities.setClasses(activityClasses);
        return activities;
    }

    /**
     * 查询活动列表列表
     *
     * @param activities 活动列表
     * @return 活动列表
     */
    public List<Activities> selectTbActivitiesList(Activities activities) {
        IdentityEnum identityEnum = IdentityEnum.getByCode(SecurityUtils.getAuthInfo().getIdentity());
        switch (identityEnum) {
            case TEACHER:
//                List<String> eclassIds = SecurityUtils.getAuthInfo().getEclasses().stream().map(Eclass::getEclassId).collect(Collectors.toList());
//                if (eclassIds.size() == 0) {
//                    return Lists.newArrayList();
//                }
//                return activitiesMapper.selectTbActivitiesListByClass(eclassIds);
                return activitiesMapper.selectTbActivitiesListT1(activities);
            case PARENT:
                ArrayList<String> eclassId = Lists.newArrayList(SecurityUtils.getAuthInfo().getCurrentStudent().getEclassId());
                if (eclassId.size() == 0) {
                    return Lists.newArrayList();
                }
                return activitiesMapper.selectTbActivitiesListByClass(eclassId);
            case ADMIN:
                return activitiesMapper.selectTbActivitiesListT1(activities);
            default:
                throw new ServiceException("当前角色不可操作");
        }
    }

    public TableDataInfo listFive(ListActivitiesSdkDto dto) {

        PageUtils.startPage(dto.getPageNum(),dto.getPageSize());
        List<Activities> activities = activitiesMapper.listFive(Lists.newArrayList(dto.getClassId()));
        PageInfo pageInfo = new PageInfo(activities);
        Set<Long> enrollsIds;
        if (activities.size() > 0) {
            String personIdByThirdPersonId = authService.getPersonIdByThirdPersonId(dto.getUserId(), dto.getToken(), dto.getOrgCode());
            if (StringUtils.isBlank(personIdByThirdPersonId)) {
                enrollsIds = Sets.newHashSet();
            } else {
                ActivityEnroll query = new ActivityEnroll();
                query.setStudentId(personIdByThirdPersonId);
                query.setActivityIds(activities.stream().map(Activities::getId).collect(Collectors.toList()));
                List<ActivityEnroll> activityEnrolls = activityEnrollMapper.selectTbActivityEnrollList(query);
                enrollsIds = activityEnrolls.stream().map(ActivityEnroll::getActivityId).collect(Collectors.toSet());
            }
        } else {
            enrollsIds = Sets.newHashSet();
        }

        List<ListActivitiesSdkVo> ret = activities.stream().map(e -> {
            ListActivitiesSdkVo vo = new ListActivitiesSdkVo();
            BeanUtils.copyProperties(e, vo);
            if (enrollsIds.contains(e.getId())) {
                vo.setEnrollFlg(1);
            } else {
                vo.setEnrollFlg(0);
            }
            return vo;
        }).collect(Collectors.toList());

        return new TableDataInfo(ret,pageInfo.getTotal());
    }

    /**
     * 新增活动列表
     *
     * @param activities 活动列表
     * @return 结果
     */
    public Long insertTbActivities(Activities activities) {
        activities.setCreateTime(DateUtils.getNowDate());
        return activitiesMapper.insertTbActivities(activities);
    }

    @Transactional(rollbackFor = Exception.class)
    public Long addActivity(AddActivityDto dto) {
        if (dto.getEnrollBegin().after(dto.getEnrollEnd())) {
            throw new ServiceException("开始时间不能大于结束时间");
        }
        Activities tbActivity = new Activities();
        BeanUtils.copyProperties(dto, tbActivity);
        tbActivity.setSex(SecurityUtils.getAuthInfo().getSex());
        tbActivity.setPersonId(SecurityUtils.getAuthInfo().getPersonId());
        tbActivity.setCreateBy(SecurityUtils.getAuthInfo().getId());
        tbActivity.setCreateByName(SecurityUtils.getAuthInfo().getName());
        tbActivity.setStatus(BooleanEnum.TRUE.getCode());
        tbActivity.setOrgCode(SecurityUtils.getAuthInfo().getOrgCode());
        tbActivity.setEnrollNum(0L);
        Long i = activitiesMapper.insertTbActivities(tbActivity);
        List<ActivityClass> classes = dto.getClasses().stream().map(e -> {
            ActivityClass activityClass = new ActivityClass();
            activityClass.setActivityId(tbActivity.getId());
            activityClass.setEclassName(e.getEClassName());
            activityClass.setEclassId(e.getEclassId());
            return activityClass;
        }).collect(Collectors.toList());
        activityClassMapper.batchInsert(classes);
        List<ActivityFiles> imgs = dto.getImgs().stream().map(e -> {
            ActivityFiles file = new ActivityFiles();
            file.setFileType(ActivityFileTypeEnum.IMG.getCode());
            file.setUrl(e);
            file.setActivityId(tbActivity.getId());
            return file;
        }).collect(Collectors.toList());
        List<ActivityFiles> files = dto.getFiles().stream().map(e -> {
            ActivityFiles file = new ActivityFiles();
            file.setFileType(ActivityFileTypeEnum.FILE.getCode());
            file.setUrl(e.getUrl());
            file.setFileName(e.getFileName());
            file.setFileExt(e.getFileExt());
            file.setActivityId(tbActivity.getId());
            return file;
        }).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(imgs)) {
            activityFilesMapper.batchInsert(imgs);
        }
        if (CollectionUtils.isNotEmpty(files)) {
            activityFilesMapper.batchInsert(files);
        }
        return i;
    }

    /**
     * 修改活动
     *
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    public int updateTbActivities(UpdateActivityDto dto) {
        Activities tbActivity = activitiesMapper.selectTbActivitiesById(dto.getId());
        BeanUtils.copyProperties(dto, tbActivity);
        tbActivity.setUpdateBy(SecurityUtils.getAuthInfo().getId());
        if (tbActivity.getEnrollTotal() != -1 && tbActivity.getEnrollNum() > tbActivity.getEnrollTotal()) {
            throw new ServiceException("活动名额不能小于当前已报名人数");
        }
        activityClassMapper.deleteByActivityId(dto.getId());
        activityFilesMapper.deleteByActivityId(dto.getId());
        List<ActivityClass> classes = dto.getClasses().stream().map(e -> {
            ActivityClass activityClass = new ActivityClass();
            activityClass.setActivityId(dto.getId());
            activityClass.setEclassId(e.getEclassId());
            activityClass.setEclassName(e.getEClassName());
            return activityClass;
        }).collect(Collectors.toList());
        activityClassMapper.batchInsert(classes);
        List<ActivityFiles> imgs = dto.getImgs().stream().map(e -> {
            ActivityFiles file = new ActivityFiles();
            file.setFileType(ActivityFileTypeEnum.IMG.getCode());
            file.setUrl(e);
            file.setActivityId(dto.getId());
            return file;
        }).collect(Collectors.toList());
        List<ActivityFiles> files = dto.getFiles().stream().map(e -> {
            ActivityFiles file = new ActivityFiles();
            file.setFileType(ActivityFileTypeEnum.FILE.getCode());
            file.setUrl(e.getUrl());
            file.setFileName(e.getFileName());
            file.setFileExt(e.getFileExt());
            file.setActivityId(dto.getId());
            return file;
        }).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(imgs)) {
            activityFilesMapper.batchInsert(imgs);
        }
        if (CollectionUtils.isNotEmpty(files)) {
            activityFilesMapper.batchInsert(files);
        }
        return activitiesMapper.updateTbActivities(tbActivity);
    }


    /**
     * 活动报名
     *
     */
    @Transactional(rollbackFor = Exception.class)
    public int enroll(Long id) {
        Activities query = new Activities();
        query.setId(id);
        Activities activity = activitiesMapper.selectTbActivitiesById(id);
//        List<Activities> activities = activitiesMapper.selectTbActivitiesListT1(query);
        if (activity == null) {
            throw new ServiceException("未查询到该活动");
        }

        if (BooleanEnum.FALSE.getCode().equals(activity.getStatus())) {
            throw new ServiceException("该活动已失效");
        }

        long now = System.currentTimeMillis();
        if (activity.getEnrollBegin().getTime() > now || activity.getEnrollEnd().getTime() < now) {
            throw new ServiceException("不在活动报名时间内");
        }

        if (activity.getEnrollTotal() != -1 && activity.getEnrollTotal().equals(activity.getEnrollNum())) {
            throw new ServiceException("活动人数已满");
        }

        activity.setEnrollNum(activity.getEnrollNum() + 1);
        ActivityEnroll enroll = new ActivityEnroll();
        enroll.setActivityId(id);
        enroll.setStudentId(SecurityUtils.getAuthInfo().getCurrentStudent().getStudentId());
        List<ActivityEnroll> activityEnrolls = activityEnrollMapper.selectTbActivityEnrollList(enroll);
        if (activityEnrolls.size() > 0) {
            throw new ServiceException("不能重复报名");
        }
        // 验证班级是否有权限
//        ActivityClass classQuery = new ActivityClass();
//        classQuery.setActivityId(id);
//        List<ActivityClass> activityClasses = activityClassMapper.selectTbActivityClassList(classQuery);
//        List<String> classIds = activityClasses.stream().map(ActivityClass::getEclassId).collect(Collectors.toList());
//        if (!classIds.contains(SecurityUtils.getAuthInfo().getCurrentStudent().getEclassId())) {
//
//        }
        enroll.setSex(SecurityUtils.getAuthInfo().getCurrentStudent().getSex());
        enroll.setParentId(SecurityUtils.getAuthInfo().getId());
        enroll.setParentName(SecurityUtils.getAuthInfo().getName());
        enroll.setStudentName(SecurityUtils.getAuthInfo().getCurrentStudent().getStudentName());
        enroll.setEclassName(SecurityUtils.getAuthInfo().getCurrentStudent().getEclassName());
        enroll.setEclassId(SecurityUtils.getAuthInfo().getCurrentStudent().getEclassId());

        activitiesMapper.updateTbActivities(activity);
        return activityEnrollMapper.insertTbActivityEnroll(enroll);
    }

    /**
     * 批量删除活动列表
     *
     * @param ids 需要删除的活动列表主键
     * @return 结果
     */
    public int deleteTbActivitiesByIds(Long[] ids) {
        return activitiesMapper.deleteTbActivitiesByIds(ids);
    }

    /**
     * 删除活动列表信息
     *
     * @param id 活动列表主键
     * @return 结果
     */
    public int deleteTbActivitiesById(Long id) {
        return activitiesMapper.deleteTbActivitiesById(id);
    }

    /**
     * 逻辑删除
     * @param id
     * @return
     */
    public int updateDeleteById(Long id) {
        return activitiesMapper.updateDeleteById(id);
    }

    public List<GetClassListByIdsRet> listClasses(Long id) {
        AuthInfo authInfo = SecurityUtils.getAuthInfo();
        List<GetClassListByIdsRet> list;
        if (CollectionUtils.isNotEmpty(authInfo.getMenuList())) {
            long count1 = authInfo.getMenuList().stream().filter(e -> "hdfb_wdfb".equals(e.getSpyCode())).count();
            long count2 = authInfo.getMenuList().stream().filter(e -> "hdfb_qbhd".equals(e.getSpyCode())).count();
            if (count1 > 0 && count2 > 0) {
                List<GetSchoolPartTreeRet> allClass = xgkService.getAllClass(SecurityUtils.getAuthInfo().getOrgCode());
                list = allClass.stream().map(e -> {
                    GetClassListByIdsRet ret = new GetClassListByIdsRet();
                    ret.setClassId(e.getUnitId());
                    ret.setClassName(e.getUnitName());
                    return ret;
                }).collect(Collectors.toList());
            } else {
                list = xgkService.listClasses();
            }
        } else {
            list = xgkService.listClasses();
        }

        if (id == null) {
            return list;
        }

        Map<String, ActivityClassCount> map = activitiesMapper.selectClassCountByAcId(id).stream().collect(Collectors.toMap(ActivityClassCount::getEclassId, Function.identity()));
        List<GetClassListByIdsRet> ret = list.stream().map(e -> {
            if (map.containsKey(e.getClassId())) {
                e.setSelected(true);
                if (map.get(e.getClassId()).getCountSum() > 0) {
                    e.setCanChange(false);
                }
            }
            return e;
        }).collect(Collectors.toList());
        return ret;
    }

    public HashMap<String,Object> statisticsAreaApp() {
        List<ActivitiesAreaApp> activities = activitiesMapper.selectStatisticsAreaApp();
        Set<String> actOrg = activities.stream().filter(e -> e.getOrgCode() != null).map(ActivitiesAreaApp::getOrgCode).collect(Collectors.toSet());
        List<String> actParent = activities.stream().filter(e -> e.getParentId() != null).map(ActivitiesAreaApp::getParentId).collect(Collectors.toList());
        Set<Long> act = activities.stream().map(ActivitiesAreaApp::getId).collect(Collectors.toSet());
        return new HashMap<String,Object>(){{
            put("orgNum",actOrg.size());
            put("parentNum",actParent.size());
            put("actNum",act.size());
        }};
    }
}
